<template>
  <div class="flex w-100% h-100%">
    <page-wrap>
      <div class="flex">
        <content-wrap class="flex-[1]">
          <div class="flex justify-center items-center">
            <div class="flex-1">部门列表</div>
            <a-input
              v-model.lazy="orgSearch"
              class="flex-[2]"
              placeholder="搜索部门"
              allow-clear
            />
          </div>
          <a-divider />
          <a-tree
            v-if="orgList.length"
            ref="orgTree"
            v-model:selected-keys="currentOrgId"
            :data="treeData"
            default-expand-all
            :field-names="{
              key: 'id',
              title: 'name',
            }"
            @select="currentOrgChange"
          />
        </content-wrap>

        <content-wrap class="flex-[3] ml-20px">
          <SearchWrap
            :schema="searchSchema"
            @search="setSearchParams"
            @reset="
              (data: Partial<UserVO>) => {
                currentOrgId = [];
                setSearchParams(data);
              }
            "
          />
          <div class="mb-10px">
            <a-button type="primary" @click="addAction">新增</a-button>
            <a-button class="ml-2" @click="importAction">导入</a-button>
            <a-button class="ml-2" @click="downloadImportTemplateAction"
              >下载导入模板</a-button
            >
          </div>
          <table-wrap
            key="id"
            :loading="loading"
            :pagination="pagination"
            :columns="tableColumns"
            :data="dataList"
            @register="tableRegister"
          >
          </table-wrap>
        </content-wrap>
      </div>
    </page-wrap>

    <a-drawer
      :width="460"
      :visible="addDialogVisible"
      :mask-closable="false"
      :unmount-on-close="true"
      @cancel="addDialogVisible = false"
    >
      <template #title>新增</template>
      <AddForm ref="addFormRef" />
      <template #footer>
        <a-button @click="addDialogVisible = false">关闭</a-button>
        <a-button type="primary" :loading="saveLoading" @click="save">
          保存
        </a-button>
      </template>
    </a-drawer>

    <a-drawer
      :width="460"
      :visible="editDialogVisible"
      :mask-closable="false"
      :unmount-on-close="true"
      @cancel="editDialogVisible = false"
    >
      <template #title>修改</template>
      <EditForm ref="editFormRef" :user-id="currentId" />
      <template #footer>
        <a-button @click="editDialogVisible = false">关闭</a-button>
        <a-button type="primary" :loading="saveLoading" @click="update">
          保存
        </a-button>
      </template>
    </a-drawer>

    <modal-dialog
      v-model="editPwDialogVisible"
      title="修改密码"
      width="460"
      @confirm="updatePw"
    >
      <EditPwForm ref="editPwFormRef" :user-id="currentId" />
    </modal-dialog>

    <modal-dialog
      v-model="importDialogVisible"
      title="导入"
      width="460"
      :fullscreen="false"
    >
      <ImportForm ref="importFormRef" />
      <template #footer>
        <a-button @click="importDialogVisible = false">关闭</a-button>
        <a-button type="primary" :loading="saveLoading" @click="submitImport"
          >提交</a-button
        >
      </template>
    </modal-dialog>
  </div>
</template>
<script setup lang="tsx">
  import { Link } from '@arco-design/web-vue';

  import { listValidTreeNodeApi as listOrgTreeNodeApi } from '@/api/system/organization';
  import type { OrgTreeNode } from '@/api/system/organization/types';
  import {
    listApi,
    removeApi,
    saveApi,
    updateApi,
    updatePwApi,
    downloadImportTemplateApi,
  } from '@/api/system/user';
  import { UserVO } from '@/api/system/user/types';
  import { useTable } from '@/hooks/table';
  import { downloadBlobFile } from '@/utils';
  import { filter } from '@/utils/tree';

  import AddForm from './components/add-form.vue';
  import EditForm from './components/edit-form.vue';
  import EditPwForm from './components/edit-pw-form.vue';
  import ImportForm from './components/import-form.vue';

  const currentId = ref('');
  const currentOrgId = ref<string[]>([]);
  const searchParams = ref<Partial<UserVO>>({});

  const { tableRegister, tableMethods, tableState } = useTable({
    fetchDataApi: async () => {
      const { pageParams } = tableState;
      return await listApi({
        ...pageParams.value,
        ...unref(searchParams),
        orgId: currentOrgId.value[0],
      });
    },
    fetchDelApi: async () => {
      return await removeApi(unref(currentId));
    },
  });

  const { dataList, loading, pagination } = tableState;
  const { getList, delList } = tableMethods;

  const tableColumns = reactive<TableColumn[]>([
    {
      field: 'index',
      title: '序号',
      width: 80,
      type: 'index',
    },
    {
      field: 'username',
      title: '用户名',
    },
    {
      field: 'realName',
      title: '真实姓名',
    },
    {
      field: 'mobile',
      title: '移动电话',
    },
    {
      field: 'email',
      title: '邮箱',
    },
    {
      field: 'orgName',
      title: '所属部门',
    },
    {
      field: 'state',
      title: '启用状态',
      type: 'enumTag',
      enumName: 'State',
    },
    {
      field: 'action',
      title: '操作',
      render: (data: any) => {
        const row = data.record as UserVO;
        return (
          <>
            <Link onClick={() => editAction(row)}>编辑</Link>
            <Link onClick={() => delAction(row.id)}>删除</Link>
            <Link onClick={() => editPwAction(row.id)}>修改密码</Link>
          </>
        );
      },
    },
  ]);

  const searchSchema = reactive<FormSchema[]>([
    {
      field: 'username',
      label: '用户名',
      type: 'Input',
    },
    {
      field: 'realName',
      label: '真实姓名',
      type: 'Input',
    },
    {
      field: 'state',
      label: '启用状态',
      type: 'Select',
      enumName: 'State',
    },
  ]);

  const orgSearch = ref('');
  const orgList = ref<OrgTreeNode[]>([]);
  const treeData = ref();
  const fetchOrg = async () => {
    orgList.value = await listOrgTreeNodeApi();
    treeData.value = orgList.value;
    await nextTick();
  };
  fetchOrg();

  const currentOrgChange = (_keys: string[], data: { node: OrgTreeNode }) => {
    currentOrgId.value[0] = data.node.id;
    searchParams.value.orgId = data.node.id;
    getList(false);
  };

  const setSearchParams = (data: any) => {
    searchParams.value = data;
    getList(false);
  };

  watch(
    () => orgSearch.value,
    (val) => {
      treeData.value = filter(orgList.value, (node) => {
        return node.name.includes(val);
      });
    }
  );

  const addDialogVisible = ref(false);
  const addFormRef = ref<ComponentRef<typeof AddForm>>();

  const editDialogVisible = ref(false);
  const editFormRef = ref<ComponentRef<typeof EditForm>>();

  const editPwDialogVisible = ref(false);
  const editPwFormRef = ref<ComponentRef<typeof EditPwForm>>();

  const importDialogVisible = ref(false);
  const importFormRef = ref<ComponentRef<typeof ImportForm>>();

  const saveLoading = ref(false);

  const addAction = () => {
    addDialogVisible.value = true;
  };

  const editAction = (row: any) => {
    currentId.value = row.id;
    editDialogVisible.value = true;
  };

  const editPwAction = (id: string) => {
    currentId.value = id;
    editPwDialogVisible.value = true;
  };

  const save = async () => {
    const addForm = unref(addFormRef);
    const formData = await addForm?.submit();
    if (formData) {
      saveLoading.value = true;
      try {
        const res = await saveApi(formData);
        if (res) {
          getList(false);
          MessageInfo.success();
          addDialogVisible.value = false;
        }
      } catch (error) {
        console.log(error);
      } finally {
        saveLoading.value = false;
      }
    }
  };

  const update = async () => {
    const editForm = unref(editFormRef);
    const formData = await editForm?.submit();
    if (formData) {
      saveLoading.value = true;
      try {
        const res = await updateApi({
          ...formData,
          id: currentId.value,
        });
        if (res) {
          getList();
          MessageInfo.success();
          editDialogVisible.value = false;
        }
      } catch (error) {
        console.log(error);
      } finally {
        saveLoading.value = false;
      }
    }
  };

  const updatePw = async () => {
    const editPwForm = unref(editPwFormRef);
    const formData = await editPwForm?.submit();
    if (formData) {
      saveLoading.value = true;
      try {
        const res = await updatePwApi(unref(currentId), formData['password']);
        if (res) {
          getList();
          MessageInfo.success();
          editPwDialogVisible.value = false;
        }
      } catch (error) {
        console.log(error);
      } finally {
        saveLoading.value = false;
      }
    }
  };

  const delAction = async (id: string) => {
    currentId.value = id;
    await delList(1);
  };

  const downloadImportTemplateAction = async () => {
    const res = await downloadImportTemplateApi();
    downloadBlobFile(res, '用户信息导入模板.xlsx');
  };

  const importAction = () => {
    importDialogVisible.value = true;
  };

  const submitImport = async () => {
    saveLoading.value = true;
    const importForm = unref(importFormRef);
    if (importForm) {
      const result = await importForm?.submitImport();
      if (result) {
        importDialogVisible.value = false;
      }
    }
    saveLoading.value = false;
  };
</script>
